home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / vibrant / table.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-05  |  27.8 KB  |  1,080 lines  |  [TEXT/R*ch]

  1. /*   table.c
  2. * ===========================================================================
  3. *
  4. *                            PUBLIC DOMAIN NOTICE
  5. *            National Center for Biotechnology Information (NCBI)
  6. *
  7. *  This software/database is a "United States Government Work" under the
  8. *  terms of the United States Copyright Act.  It was written as part of
  9. *  the author's official duties as a United States Government employee and
  10. *  thus cannot be copyrighted.  This software/database is freely available
  11. *  to the public for use. The National Library of Medicine and the U.S.
  12. *  Government do not place any restriction on its use or reproduction.
  13. *  We would, however, appreciate having the NCBI and the author cited in
  14. *  any work or product based on this material
  15. *
  16. *  Although all reasonable efforts have been taken to ensure the accuracy
  17. *  and reliability of the software and data, the NLM and the U.S.
  18. *  Government do not and cannot warrant the performance or results that
  19. *  may be obtained by using this software or data. The NLM and the U.S.
  20. *  Government disclaim all warranties, express or implied, including
  21. *  warranties of performance, merchantability or fitness for any particular
  22. *  purpose.
  23. *
  24. * ===========================================================================
  25. *
  26. * File Name:  table.c
  27. *
  28. * Author:  Jonathan Kans
  29. *
  30. * Version Creation Date:   1/1/91
  31. *
  32. * $Revision: 2.1 $
  33. *
  34. * File Description:   Active tabular text
  35. *
  36. * Modifications:  
  37. * --------------------------------------------------------------------------
  38. * Date     Name        Description of modification
  39. * -------  ----------  -----------------------------------------------------
  40. *
  41. *
  42. * ==========================================================================
  43. */
  44.  
  45. #include "panels.h"
  46.  
  47. #define numCellsPerPage 256
  48.  
  49. typedef  struct  tableData {
  50.   Handle     title;
  51.   Int2       numPages;
  52.   Handle     pageHandles;
  53.   Int2       numColumns;
  54.   Handle     colHandles;
  55.   FonT       font;
  56.   Int2       topRow;
  57.   Int2       leftMargin;
  58.   Int2       rightMargin;
  59.   Int2       width;
  60.   Int2       lineHeight;
  61.   Int2       visLines;
  62.   Int2       numLines;
  63.   Int2       currentRow;
  64.   Int2       tabRow;
  65.   Int2       returnRow;
  66.   Int2       currentColumn;
  67.   TableProc  action;
  68. } TableData;
  69.  
  70. typedef  Handle PageRec, PNTR PagePtr;
  71.  
  72. typedef  struct  cellRec {
  73.   Uint4    start;
  74.   Nlm_sizeT   count;
  75.   Boolean  hilight;
  76.   Boolean  gray;
  77. } CellRec, PNTR CellPtr;
  78.  
  79. typedef  struct  colRec {
  80.   TableProc  click;
  81.   Int2       pos;
  82.   Int2       width;
  83.   Char       just;
  84.   Boolean    wrap;
  85.   Boolean    bar;
  86. } ColRec, PNTR ColPtr;
  87.  
  88. static Boolean SetCellRec (TablE t, Int2 row, Int2 column, CellRec * cellRec)
  89.  
  90. {
  91.   Int4       cell;
  92.   CellPtr    cellPtr;
  93.   Int2       index;
  94.   Int2       numColumns;
  95.   Int2       numPages;
  96.   Int2       page;
  97.   Handle     pageHandles;
  98.   PagePtr    pagePtr;
  99.   Boolean    rsult;
  100.   TableData  tdata;
  101.  
  102.   rsult = FALSE;
  103.   if (t != NULL && cellRec != NULL) {
  104.     GetPanelExtra ((PaneL) t, &tdata);
  105.     numPages = tdata.numPages;
  106.     pageHandles = tdata.pageHandles;
  107.     numColumns = tdata.numColumns;
  108.     cell = (Int4) row * (Int4) numColumns + (Int4) column;
  109.     page = (Int2) (cell / numCellsPerPage);
  110.     index = (Int2) (cell % numCellsPerPage);
  111.     if (pageHandles != NULL && page < numPages && column < numColumns) {
  112.       pagePtr = (PagePtr) HandLock (pageHandles);
  113.       if (pagePtr != NULL && pagePtr [page] != NULL) {
  114.         cellPtr = (CellPtr) HandLock (pagePtr [page]);
  115.         if (cellPtr != NULL) {
  116.           cellPtr [index] = *cellRec;
  117.           rsult = TRUE;
  118.         }
  119.         HandUnlock (pagePtr [page]);
  120.       }
  121.       HandUnlock (pageHandles);
  122.     }
  123.   }
  124.   return rsult;
  125. }
  126.  
  127. static Boolean GetCellRec (TablE t, Int2 row, Int2 column, CellRec * cellRec)
  128.  
  129. {
  130.   Int4       cell;
  131.   CellPtr    cellPtr;
  132.   Int2       index;
  133.   Int2       numColumns;
  134.   Int2       numPages;
  135.   Int2       page;
  136.   Handle     pageHandles;
  137.   PagePtr    pagePtr;
  138.   Boolean    rsult;
  139.   TableData  tdata;
  140.  
  141.   rsult = FALSE;
  142.   if (t != NULL && cellRec != NULL) {
  143.     GetPanelExtra ((PaneL) t, &tdata);
  144.     numPages = tdata.numPages;
  145.     pageHandles = tdata.pageHandles;
  146.     numColumns = tdata.numColumns;
  147.     cell = (Int4) row * (Int4) numColumns + (Int4) column;
  148.     page = (Int2) (cell / numCellsPerPage);
  149.     index = (Int2) (cell % numCellsPerPage);
  150.     if (pageHandles != NULL && page < numPages && column < numColumns) {
  151.       pagePtr = (PagePtr) HandLock (pageHandles);
  152.       if (pagePtr != NULL && pagePtr [page] != NULL) {
  153.         cellPtr = (CellPtr) HandLock (pagePtr [page]);
  154.         if (cellPtr != NULL) {
  155.           *cellRec = cellPtr [index];
  156.           rsult = TRUE;
  157.         }
  158.         HandUnlock (pagePtr [page]);
  159.       }
  160.       HandUnlock (pageHandles);
  161.     }
  162.   }
  163.   return rsult;
  164. }
  165.  
  166. static Boolean SetColRec (TablE t, Int2 column, ColRec * colRec)
  167.  
  168. {
  169.   Handle     colHandles;
  170.   ColPtr     colPtr;
  171.   Int2       numColumns;
  172.   Boolean    rsult;
  173.   TableData  tdata;
  174.  
  175.   rsult = FALSE;
  176.   if (t != NULL && colRec != NULL) {
  177.     GetPanelExtra ((PaneL) t, &tdata);
  178.     numColumns = tdata.numColumns;
  179.     colHandles = tdata.colHandles;
  180.     if (colHandles != NULL && column < numColumns) {
  181.       colPtr = (ColPtr) HandLock (colHandles);
  182.       if (colPtr != NULL) {
  183.         colPtr [column] = *colRec;
  184.         rsult = TRUE;
  185.       }
  186.       HandUnlock (colHandles);
  187.     }
  188.   }
  189.   return rsult;
  190. }
  191.  
  192. static Boolean GetColRec (TablE t, Int2 column, ColRec * colRec)
  193.  
  194. {
  195.   Handle     colHandles;
  196.   ColPtr     colPtr;
  197.   Int2       numColumns;
  198.   Boolean    rsult;
  199.   TableData  tdata;
  200.  
  201.   rsult = FALSE;
  202.   if (t != NULL && colRec != NULL) {
  203.     GetPanelExtra ((PaneL) t, &tdata);
  204.     numColumns = tdata.numColumns;
  205.     colHandles = tdata.colHandles;
  206.     if (colHandles != NULL && column < numColumns) {
  207.       colPtr = (ColPtr) HandLock (colHandles);
  208.       if (colPtr != NULL) {
  209.         *colRec = colPtr [column];
  210.         rsult = TRUE;
  211.       }
  212.       HandUnlock (colHandles);
  213.     }
  214.   }
  215.   return rsult;
  216. }
  217.  
  218. static void DrawTable (PaneL t)
  219.  
  220. {
  221.   CellPtr    cellPtr;
  222.   CharPtr    charPtr;
  223.   ColPtr     colPtr;
  224.   Int2       column;
  225.   Handle     colHandles;
  226.   RecT       dr;
  227.   Handle     h;
  228.   Int2       index;
  229.   Int2       numColumns;
  230.   Int2       numPages;
  231.   Int2       off;
  232.   Int2       page;
  233.   Handle     pageHandles;
  234.   PagePtr    pagePtr;
  235.   RecT       q;
  236.   RecT       r;
  237.   Int2       row;
  238.   SlatE      s;
  239.   RecT       sr;
  240.   TableData  tdata;
  241.  
  242.   s = (SlatE) Parent (t);
  243.   GetPanelExtra (t, &tdata);
  244.   h = tdata.title;
  245.   numPages = tdata.numPages;
  246.   pageHandles = tdata.pageHandles;
  247.   numColumns = tdata.numColumns;
  248.   colHandles = tdata.colHandles;
  249.   SelectFont (tdata.font);
  250.   ObjectRect (s, &sr);
  251.   InsetRect (&sr, 4, 4);
  252.   GetOffset (t, NULL, &off);
  253.   if (h != NULL && pageHandles != NULL && colHandles != NULL && numColumns > 0) {
  254.     charPtr = (CharPtr) HandLock (h);
  255.     pagePtr = (PagePtr) HandLock (pageHandles);
  256.     colPtr = (ColPtr) HandLock (colHandles);
  257.     row = 0;
  258.     column = 0;
  259.     for (page = 0; page < numPages; page++) {
  260.       if (pagePtr [page] != NULL) {
  261.         cellPtr = (CellPtr) HandLock (pagePtr [page]);
  262.         if (cellPtr != NULL) {
  263.           for (index = 0; index < numCellsPerPage; index++) {
  264.             if (colPtr [column].width > 0) {
  265.               r.left = colPtr [column].pos;
  266.               r.top = tdata.topRow + row * tdata.lineHeight;
  267.               r.right = r.left + colPtr [column].width;
  268.               r.bottom = r.top + tdata.lineHeight;
  269.               OffsetRect (&r, 0, -off);
  270.               if (RectInRect (&r, &sr) &&
  271.                   (updateRgn == NULL || RectInRgn (&r, updateRgn))) {
  272.                 if (cellPtr [index].hilight) {
  273.                   InvertColors ();
  274.                 }
  275.                 EraseRect (&r);
  276.                 q = r;
  277.                 InsetRect (&q, 5, 0);
  278.                 if (cellPtr [index].count > 0) {
  279.                   DrawText (&q, charPtr + cellPtr [index].start,
  280.                             cellPtr [index].count, colPtr [column].just,
  281.                             cellPtr [index].gray);
  282.                 }
  283.                 if (cellPtr [index].hilight) {
  284.                   InvertColors ();
  285.                 }
  286.               }
  287.             }
  288.             column++;
  289.             if (column >= numColumns) {
  290.               row++;
  291.               column = 0;
  292.             }
  293.           }
  294.         }
  295.         HandUnlock (pagePtr [page]);
  296.       }
  297.     }
  298.     HandUnlock (colHandles);
  299.     HandUnlock (pageHandles);
  300.     HandUnlock (h);
  301.   }
  302.   if (colHandles != NULL) {
  303.     InvertMode ();
  304.     colPtr = (ColPtr) HandLock (colHandles);
  305.     for (column = 0; column < numColumns; column++) {
  306.       if (colPtr [column].bar) {
  307.         ObjectRect (t, &r);
  308.         r.left = colPtr [column].pos;
  309.         SectRect (&r, &sr, &dr);
  310.         dr.bottom = dr.top + tdata.visLines * tdata.lineHeight - 1;
  311.         MoveTo (dr.left, dr.top);
  312.         LineTo (dr.left, dr.bottom);
  313.       }
  314.     }
  315.     HandUnlock (colHandles);
  316.     CopyMode ();
  317.   }
  318.   SelectFont (systemFont);
  319. }
  320.  
  321. extern void RecordColumn (TablE t, Int2 wid,
  322.                           Char just, Boolean wrap,
  323.                           Boolean bar, TableProc actn)
  324.  
  325. {
  326.   Int2       chunk;
  327.   ColPtr     colPtr;
  328.   Handle     colHandles;
  329.   Int2       numColumns;
  330.   RecT       r;
  331.   Int2       rightMargin;
  332.   TableData  tdata;
  333.  
  334.   if (t != NULL) {
  335.     ObjectRect (t, &r);
  336.     GetPanelExtra ((PaneL) t, &tdata);
  337.     numColumns = tdata.numColumns;
  338.     colHandles = tdata.colHandles;
  339.     chunk = 8;
  340.     if (colHandles != NULL) {
  341.       if (numColumns % chunk == 0) {
  342.         colHandles = HandMore (colHandles, sizeof (ColRec) *
  343.                                  (numColumns / chunk + 1) * chunk);
  344.       }
  345.     } else {
  346.       colHandles = HandNew (sizeof (ColRec) * chunk);
  347.     }
  348.     numColumns++;
  349.     colPtr = (ColPtr) HandLock (colHandles);
  350.     colPtr [numColumns - 1].click = actn;
  351.     if (numColumns == 1) {
  352.       colPtr [numColumns - 1].pos = r.left;
  353.     } else if (numColumns > 1) {
  354.       colPtr [numColumns - 1].pos = colPtr [numColumns - 2].pos +
  355.                                     colPtr [numColumns - 2].width;
  356.     }
  357.     colPtr [numColumns - 1].width = wid * MaxCharWidth ();
  358.     colPtr [numColumns - 1].just = just;
  359.     colPtr [numColumns - 1].wrap = wrap;
  360.     colPtr [numColumns - 1].bar = bar;
  361.     HandUnlock (colHandles);
  362.     rightMargin = colPtr [numColumns - 1].pos + colPtr [numColumns - 1].width;
  363.     if (tdata.rightMargin < rightMargin) {
  364.       tdata.rightMargin = rightMargin;
  365.     }
  366.     tdata.numColumns = numColumns;
  367.     tdata.colHandles = colHandles;
  368.     SetPanelExtra ((PaneL) t, &tdata);
  369.   }
  370. }
  371.  
  372. static void RecordSegment (TablE t, Uint4 start,
  373.                            Uint4 prev, Int2 len,
  374.                            Int2 row, Int2 column)
  375.  
  376. {
  377.   Int4       cell;
  378.   CellPtr    cellPtr;
  379.   Int2       index;
  380.   Int2       numColumns;
  381.   Int2       numPages;
  382.   Int2       page;
  383.   Handle     pageHandles;
  384.   PagePtr    pagePtr;
  385.   TableData  tdata;
  386.  
  387.   if (t != NULL) {
  388.     GetPanelExtra ((PaneL) t, &tdata);
  389.     numPages = tdata.numPages;
  390.     pageHandles = tdata.pageHandles;
  391.     numColumns = tdata.numColumns;
  392.     cell = (Int4) row * (Int4) numColumns + (Int4) column;
  393.     page = (Int2) (cell / numCellsPerPage);
  394.     index = (Int2) (cell % numCellsPerPage);
  395.     if (page >= numPages) {
  396.       numPages = page + 1;
  397.       if (pageHandles != NULL) {
  398.         pageHandles = HandMore (pageHandles, sizeof (PageRec) * numPages);
  399.       } else {
  400.         pageHandles = HandNew (sizeof (PageRec));
  401.       }
  402.       tdata.numPages = numPages;
  403.       tdata.pageHandles = pageHandles;
  404.       SetPanelExtra ((PaneL) t, &tdata);
  405.       pagePtr = (PagePtr) HandLock (pageHandles);
  406.       if (pagePtr != NULL) {
  407.         pagePtr [page] = HandNew (sizeof (CellRec) * numCellsPerPage);
  408.       }
  409.       HandUnlock (pageHandles);
  410.     }
  411.     if (pageHandles != NULL && column < numColumns) {
  412.       pagePtr = (PagePtr) HandLock (pageHandles);
  413.       if (pagePtr [page] != NULL) {
  414.         cellPtr = (CellPtr) HandLock (pagePtr [page]);
  415.         if (cellPtr != NULL) {
  416.           cellPtr [index].start = start + prev;
  417.           cellPtr [index].count = len;
  418.           cellPtr [index].hilight = FALSE;
  419.           cellPtr [index].gray = FALSE;
  420.         }
  421.         HandUnlock (pagePtr [page]);
  422.       }
  423.       HandUnlock (pageHandles);
  424.     }
  425.   }
  426. }
  427.  
  428. static Int2 GetNextBlock (CharPtr title, Int2 maxwid)
  429.  
  430. {
  431.   Int2  i;
  432.   Int2  j;
  433.   Int2  wid;
  434.  
  435.   i = 0;
  436.   j = 0;
  437.   wid = 0;
  438.   if (title != NULL && maxwid > 0) {
  439.     while (title [i] != '\0' && title [i] != '\n' &&
  440.            title [i] != '\r' && title [i] != '\t' &&
  441.            wid <= maxwid) {
  442.       wid += CharWidth (title [i]);
  443.       i++;
  444.     }
  445.     j = i;
  446.     if (wid > maxwid) {
  447.       j--;
  448.       while (TextWidth (title, i) > maxwid) {
  449.         i--;
  450.       }
  451.       while (i > 0 && (! IS_WHITESP(title [i])) && title [i - 1] != '-') {
  452.         i--;
  453.       }
  454.       while (i > 0 && (IS_WHITESP(title [i - 1])) && title [i - 1] != '-') {
  455.         i--;
  456.       }
  457.     } else if (title [i] != '\0') {
  458.       while (i > 0 && (IS_WHITESP(title [i - 1]))) {
  459.         i--;
  460.       }
  461.     }
  462.   }
  463.   if (i > 0 && i < j) {
  464.     return i;
  465.   } else if (j > 0) {
  466.     return j;
  467.   } else {
  468.     return 0;
  469.   }
  470. }
  471.  
  472. static Uint4 CopyToHandle (TablE t, CharPtr title)
  473.  
  474. {
  475.   CharPtr    charPtr;
  476.   Nlm_sizeT     chunk;
  477.   Handle     h;
  478.   Nlm_sizeT     len;
  479.   Nlm_sizeT     prev;
  480.   Nlm_sizeT     size;
  481.   TableData  tdata;
  482.  
  483.   prev = 0;
  484.   if (t != NULL && title != NULL) {
  485.     GetPanelExtra ((PaneL) t, &tdata);
  486.     chunk = 4096;
  487.     h = tdata.title;
  488.     if (h != NULL) {
  489.       charPtr = (CharPtr) HandLock (h);
  490.       prev = StringLen (charPtr);
  491.       HandUnlock (h);
  492.       len = prev + StringLen (title);
  493.       size = ((len + 1) / chunk + 1) * chunk;
  494.       if ((len + 1) / chunk > (prev + 1) / chunk) {
  495.         h = HandMore (h, size);
  496.       }
  497.       charPtr = (CharPtr) HandLock (h);
  498.       StringNCat (charPtr, title, size);
  499.       HandUnlock (h);
  500.       tdata.title = h;
  501.       SetPanelExtra ((PaneL) t, &tdata);
  502.     } else {
  503.       len = StringLen (title);
  504.       size = ((len + 1) / chunk + 1) * chunk;
  505.       h = HandNew (size);
  506.       charPtr = (CharPtr) HandLock (h);
  507.       StringNCpy (charPtr, title, size);
  508.       HandUnlock (h);
  509.       tdata.title = h;
  510.       SetPanelExtra ((PaneL) t, &tdata);
  511.     }
  512.   }
  513.   return prev;
  514. }
  515.  
  516. extern void AppendTableText (TablE t, CharPtr title)
  517.  
  518. {
  519.   Char       ch;
  520.   ColPtr     colPtr;
  521.   Int2       column;
  522.   Handle     colHandles;
  523.   RecT       dr;
  524.   Int2       len;
  525.   Int2       maxwid;
  526.   Int2       newLines;
  527.   Int2       numColumns;
  528.   Int2       off;
  529.   Uint4      prev;
  530.   RecT       r;
  531.   Int2       returnRow;
  532.   Int2       row;
  533.   SlatE      s;
  534.   RecT       sr;
  535.   Uint4      start;
  536.   Int2       tabRow;
  537.   TableData  tdata;
  538.   WindoW     tempPort;
  539.  
  540.   if (t != NULL && title != NULL && title [0] != '\0') {
  541.     tempPort = SavePort (t);
  542.     prev = CopyToHandle (t, title);
  543.     GetPanelExtra ((PaneL) t, &tdata);
  544.     SelectFont (tdata.font);
  545.     numColumns = tdata.numColumns;
  546.     colHandles = tdata.colHandles;
  547.     s = (SlatE) Parent (t);
  548.     start = 0;
  549.     row = tdata.currentRow;
  550.     tabRow = tdata.tabRow;
  551.     returnRow = tdata.returnRow;
  552.     column = tdata.currentColumn;
  553.     colPtr = (ColPtr) HandLock (colHandles);
  554.     while (title [start] != '\0') {
  555.       while (title [start] == ' ') {
  556.         start++;
  557.       }
  558.       if (title [start] != '\0') {
  559.         ch = title [start];
  560.         if (ch != '\0' && ch != '\n' && ch != '\r' && ch != '\t') {
  561.           maxwid = INT2_MAX;
  562.           if (numColumns > 0 && column < numColumns &&
  563.               colPtr [column].wrap && colPtr [column].width >= 12) {
  564.             maxwid = colPtr [column].width - 12;
  565.           }
  566.           len = GetNextBlock (title + start, maxwid);
  567.           if (len > 0) {
  568.             RecordSegment (t, start, prev, len, row, column);
  569.             start += len;
  570.           } else if (colPtr [column].wrap) {
  571.             while (TextWidth (title + start, len) <= maxwid) {
  572.               len++;
  573.             }
  574.             len--;
  575.             if (len > 0) {
  576.               RecordSegment (t, start, prev, len, row, column);
  577.             }
  578.             ch = title [start];
  579.             while (ch != '\0' && ch != '\n' && ch != '\r' && ch != '\t') {
  580.               start++;
  581.               ch = title [start];
  582.             }
  583.           }
  584.         }
  585.         ch = title [start];
  586.         if (ch == '\n') {
  587.           start++;
  588.           row = returnRow;
  589.           tabRow = row;
  590.           returnRow = MAX (returnRow, row + 1);
  591.           column = 0;
  592.         } else if (ch == '\r') {
  593.           start++;
  594.           row++;
  595.           returnRow = MAX (returnRow, row + 1);
  596.         } else if (ch == '\t') {
  597.           start++;
  598.           row = tabRow;
  599.           column++;
  600.         } else if (ch != '\0' && colPtr [column].wrap) {
  601.           if (len == 0) {
  602.             start++;
  603.           }
  604.           row++;
  605.           returnRow = MAX (returnRow, row + 1);
  606.         } else if (ch != '\0') {
  607.           start++;
  608.         }
  609.       }
  610.     }
  611.     HandUnlock (colHandles);
  612.     newLines = row - tdata.numLines;
  613.     r.left = tdata.leftMargin;
  614.     r.top = tdata.topRow;
  615.     r.right = tdata.rightMargin;
  616.     r.bottom = tdata.topRow + row * tdata.lineHeight;
  617.     RegisterRect ((PaneL) t, &r);
  618.     r.top = tdata.topRow + tdata.numLines * tdata.lineHeight;
  619.     RegisterRow (s, r.top, tdata.lineHeight, newLines);
  620.     r.bottom = r.top + newLines * tdata.lineHeight;
  621.     GetPanelExtra ((PaneL) t, &tdata);
  622.     tdata.currentRow = row;
  623.     tdata.tabRow = tabRow;
  624.     tdata.returnRow = returnRow;
  625.     tdata.currentColumn = column;
  626.     tdata.numLines += newLines;
  627.     SetPanelExtra ((PaneL) t, &tdata);
  628.     SelectFont (systemFont);
  629.     if (Enabled (t) && AllParentsEnabled (t) &&
  630.         Visible (t) && AllParentsVisible (t)) {
  631.       ObjectRect (s, &sr);
  632.       InsetRect (&sr, 4, 4);
  633.       GetOffset (t, NULL, &off);
  634.       OffsetRect (&r, 0, -off);
  635.       SectRect (&r, &sr, &dr);
  636.       if (RectInRect (&dr, &sr)) {
  637.         Select (t);
  638.         InvalRect (&dr);
  639.       }
  640.     }
  641.     RestorePort (tempPort);
  642.   }
  643. }
  644.  
  645. extern Boolean GetTableText (TablE t, Int2 row,
  646.                              Int2 column, CharPtr text,
  647.                              Uint4 maxsize)
  648.  
  649. {
  650.   CellRec    cellRec;
  651.   CharPtr    charPtr;
  652.   Uint4      count;
  653.   Handle     h;
  654.   Boolean    rsult;
  655.   Uint4      start;
  656.   TableData  tdata;
  657.  
  658.   rsult = FALSE;
  659.   if (text != NULL && maxsize > 0) {
  660.     *text = '\0';
  661.   }
  662.   if (t != NULL && text != NULL && maxsize > 0) {
  663.     count = 0;
  664.     start = 0;
  665.     if (row > 0 && column > 0) {
  666.       row--;
  667.       column--;
  668.       GetPanelExtra ((PaneL) t, &tdata);
  669.       h = tdata.title;
  670.       GetCellRec (t, row, column, &cellRec);
  671.       start = cellRec.start;
  672.       count = cellRec.count;
  673.     } else if (row > 0) {
  674.       row--;
  675.       GetPanelExtra ((PaneL) t, &tdata);
  676.       h = tdata.title;
  677.       GetCellRec (t, row, 0, &cellRec);
  678.       start = cellRec.start;
  679.       if (GetCellRec (t, row + 1, 0, &cellRec)) {
  680.         if (cellRec.count > 0) {
  681.           count = cellRec.start - start;
  682.         } else {
  683.           h = tdata.title;
  684.           charPtr = (CharPtr) HandLock (h);
  685.           count = StringLen (charPtr) - start;
  686.           HandUnlock (h);
  687.         }
  688.       } else {
  689.         h = tdata.title;
  690.         charPtr = (CharPtr) HandLock (h);
  691.         count = StringLen (charPtr) - start;
  692.         HandUnlock (h);
  693.       }
  694.     } else {
  695.       GetPanelExtra ((PaneL) t, &tdata);
  696.       h = tdata.title;
  697.       charPtr = (CharPtr) HandLock (h);
  698.       count = StringLen (charPtr);
  699.       HandUnlock (h);
  700.     }
  701.     if (count > maxsize - 1) {
  702.       count = maxsize - 1;
  703.     }
  704.     charPtr = (CharPtr) HandLock (h);
  705.     charPtr += start;
  706.     while (count > 0) {
  707.       *text = *charPtr;
  708.       text++;
  709.       charPtr++;
  710.       count--;
  711.     }
  712.     *text = '\0';
  713.     HandUnlock (h);
  714.     rsult = TRUE;
  715.   }
  716.   return rsult;
  717. }
  718.  
  719. extern Uint4 TableTextLength (TablE t, Int2 row, Int2 column)
  720.  
  721. {
  722.   CellRec    cellRec;
  723.   CharPtr    charPtr;
  724.   Uint4      count;
  725.   Handle     h;
  726.   Uint4      start;
  727.   TableData  tdata;
  728.  
  729.   count = 0;
  730.   if (t != NULL) {
  731.     count = 0;
  732.     start = 0;
  733.     if (row > 0 && column > 0) {
  734.       row--;
  735.       column--;
  736.       GetPanelExtra ((PaneL) t, &tdata);
  737.       GetCellRec (t, row, column, &cellRec);
  738.       count = cellRec.count;
  739.     } else if (row > 0) {
  740.       row--;
  741.       GetPanelExtra ((PaneL) t, &tdata);
  742.       GetCellRec (t, row, 0, &cellRec);
  743.       start = cellRec.start;
  744.       if (GetCellRec (t, row + 1, 0, &cellRec)) {
  745.         if (cellRec.count > 0) {
  746.           count = cellRec.start - start;
  747.         } else {
  748.           h = tdata.title;
  749.           charPtr = (CharPtr) HandLock (h);
  750.           count = StringLen (charPtr) - start;
  751.           HandUnlock (h);
  752.         }
  753.       } else {
  754.         h = tdata.title;
  755.         charPtr = (CharPtr) HandLock (h);
  756.         count = StringLen (charPtr) - start;
  757.         HandUnlock (h);
  758.       }
  759.     } else {
  760.       GetPanelExtra ((PaneL) t, &tdata);
  761.       h = tdata.title;
  762.       charPtr = (CharPtr) HandLock (h);
  763.       count = StringLen (charPtr);
  764.       HandUnlock (h);
  765.     }
  766.   }
  767.   return count;
  768. }
  769.  
  770. extern void SetTableBlockHilight (TablE t, Int2 firstRow,
  771.                                   Int2 lastRow, Int2 firstColumn,
  772.                                   Int2 lastColumn, Boolean hilight)
  773.  
  774. {
  775.   CellRec    cellRec;
  776.   ColRec     colRec;
  777.   Int2       column;
  778.   Int2       off;
  779.   RecT       r;
  780.   Int2       row;
  781.   SlatE      s;
  782.   RecT       sr;
  783.   TableData  tdata;
  784.   WindoW     tempPort;
  785.  
  786.   if (t != NULL && firstRow > 0 && lastRow > 0 &&
  787.       firstColumn > 0 && lastColumn > 0) {
  788.     tempPort = SavePort (t);
  789.     s = (SlatE) Parent (t);
  790.     GetPanelExtra ((PaneL) t, &tdata);
  791.     ObjectRect (s, &sr);
  792.     InsetRect (&sr, 4, 4);
  793.     GetOffset (t, NULL, &off);
  794.     firstRow--;
  795.     lastRow--;
  796.     firstColumn--;
  797.     lastColumn--;
  798.     for (column = firstColumn; column <= lastColumn; column++) {
  799.       GetColRec (t, column, &colRec);
  800.       for (row = firstRow; row <= lastRow; row++) {
  801.         GetCellRec (t, row, column, &cellRec);
  802.         cellRec.hilight = hilight;
  803.         SetCellRec (t, row, column, &cellRec);
  804.         r.left = colRec.pos;
  805.         r.top = tdata.topRow + row * tdata.lineHeight;
  806.         r.right = r.left + colRec.width;
  807.         r.bottom = r.top + tdata.lineHeight;
  808.         OffsetRect (&r, 0, -off);
  809.         if (Enabled (t) && AllParentsEnabled (t) &&
  810.             Visible (t) && AllParentsVisible (t) &&
  811.             RectInRect (&r, &sr)) {
  812.           Select (t);
  813.           InvalRect (&r);
  814.         }
  815.       }
  816.     }
  817.     RestorePort (tempPort);
  818.   }
  819. }
  820.  
  821. extern void SetTableHilight (TablE t, Int2 row,
  822.                              Int2 column, Boolean hilight)
  823.  
  824. {
  825.   SetTableBlockHilight (t, row, row, column, column, hilight);
  826. }
  827.  
  828. extern Boolean GetTableHilight (TablE t, Int2 row, Int2 column)
  829.  
  830. {
  831.   CellRec  cellRec;
  832.   Boolean  rsult;
  833.  
  834.   rsult = FALSE;
  835.   if (t != NULL && row > 0 && column > 0) {
  836.     row--;
  837.     column--;
  838.     GetCellRec (t, row, column, &cellRec);
  839.     rsult = cellRec.hilight;
  840.   }
  841.   return rsult;
  842. }
  843.  
  844. extern void SetTableBlockGray (TablE t, Int2 firstRow,
  845.                                Int2 lastRow, Int2 firstColumn,
  846.                                Int2 lastColumn, Boolean gray)
  847.  
  848. {
  849.   CellRec    cellRec;
  850.   ColRec     colRec;
  851.   Int2       column;
  852.   Int2       off;
  853.   RecT       r;
  854.   Int2       row;
  855.   SlatE      s;
  856.   RecT       sr;
  857.   TableData  tdata;
  858.   WindoW     tempPort;
  859.  
  860.   if (t != NULL && firstRow > 0 && lastRow > 0 &&
  861.       firstColumn > 0 && lastColumn > 0) {
  862.     tempPort = SavePort (t);
  863.     s = (SlatE) Parent (t);
  864.     GetPanelExtra ((PaneL) t, &tdata);
  865.     ObjectRect (s, &sr);
  866.     InsetRect (&sr, 4, 4);
  867.     GetOffset (t, NULL, &off);
  868.     firstRow--;
  869.     lastRow--;
  870.     firstColumn--;
  871.     lastColumn--;
  872.     for (column = firstColumn; column <= lastColumn; column++) {
  873.       GetColRec (t, column, &colRec);
  874.       for (row = firstRow; row <= lastRow; row++) {
  875.         GetCellRec (t, row, column, &cellRec);
  876.         cellRec.gray = gray;
  877.         SetCellRec (t, row, column, &cellRec);
  878.         r.left = colRec.pos;
  879.         r.top = tdata.topRow + row * tdata.lineHeight;
  880.         r.right = r.left + colRec.width;
  881.         r.bottom = r.top + tdata.lineHeight;
  882.         OffsetRect (&r, 0, -off);
  883.         if (Enabled (t) && AllParentsEnabled (t) &&
  884.             Visible (t) && AllParentsVisible (t) &&
  885.             RectInRect (&r, &sr)) {
  886.           Select (t);
  887.           InvalRect (&r);
  888.         }
  889.       }
  890.     }
  891.     RestorePort (tempPort);
  892.   }
  893. }
  894.  
  895. extern void SetTableGray (TablE t, Int2 row,
  896.                           Int2 column, Boolean gray)
  897.  
  898. {
  899.   SetTableBlockGray (t, row, row, column, column, gray);
  900. }
  901.  
  902. extern Boolean GetTableGray (TablE t, Int2 row, Int2 column)
  903.  
  904. {
  905.   CellRec  cellRec;
  906.   Boolean  rsult;
  907.  
  908.   rsult = FALSE;
  909.   if (t != NULL && row > 0 && column > 0) {
  910.     row--;
  911.     column--;
  912.     GetCellRec (t, row, column, &cellRec);
  913.     rsult = cellRec.gray;
  914.   }
  915.   return rsult;
  916. }
  917.  
  918. extern Int2 TableNumLines (TablE t)
  919.  
  920. {
  921.   Int2       rsult;
  922.   TableData  tdata;
  923.  
  924.   rsult = 0;
  925.   if (t != NULL) {
  926.     GetPanelExtra ((PaneL) t, &tdata);
  927.     rsult = tdata.numLines;
  928.   }
  929.   return rsult;
  930. }
  931.  
  932. extern Int2 TableVisLines (TablE t)
  933.  
  934. {
  935.   Int2       rsult;
  936.   TableData  tdata;
  937.  
  938.   rsult = 0;
  939.   if (t != NULL) {
  940.     GetPanelExtra ((PaneL) t, &tdata);
  941.     rsult = tdata.visLines;
  942.   }
  943.   return rsult;
  944. }
  945.  
  946. static void TableClick (PaneL t, PoinT pt)
  947.  
  948. {
  949.   TableProc  actn;
  950.   ColRec     colRec;
  951.   Int2       column;
  952.   Boolean    goOn;
  953.   Int2       off;
  954.   RecT       r;
  955.   Int2       row;
  956.   SlatE      s;
  957.   RecT       sr;
  958.   TableData  tdata;
  959.  
  960.   if (t != NULL) {
  961.     actn = NULL;
  962.     s = (SlatE) Parent (t);
  963.     GetPanelExtra (t, &tdata);
  964.     ObjectRect (s, &sr);
  965.     InsetRect (&sr, 4, 4);
  966.     GetOffset (t, NULL, &off);
  967.     if (pt.y + off >= tdata.topRow) {
  968.       row = (pt.y + off - tdata.topRow) / tdata.lineHeight;
  969.       goOn = TRUE;
  970.       column = 0;
  971.       r.left = 0;
  972.       r.right = 0;
  973.       r.top = tdata.topRow + row * tdata.lineHeight;
  974.       r.bottom = r.top + tdata.lineHeight;
  975.       OffsetRect (&r, 0, -off);
  976.       while (goOn && column < tdata.numColumns) {
  977.         GetColRec ((TablE) t, column, &colRec);
  978.         actn = colRec.click;
  979.         r.left = colRec.pos;
  980.         r.right = r.left + colRec.width;
  981.         if (RectInRect (&r, &sr) && PtInRect (pt, &r)) {
  982.           goOn = FALSE;
  983.           if (actn != NULL) {
  984.             actn ((TablE) t, row + 1, column + 1);
  985.           }
  986.           actn = tdata.action;
  987.           if (actn != NULL) {
  988.             actn ((TablE) t, row + 1, column + 1);
  989.           }
  990.         } else {
  991.           column++;
  992.         }
  993.       }
  994.     }
  995.   }
  996. }
  997.  
  998. static void NewTable (TablE t, Int2 minwid, FonT font, TableProc actn)
  999.  
  1000. {
  1001.   PoinT      npt;
  1002.   RecT       r;
  1003.   SlatE      s;
  1004.   TableData  tdata;
  1005.  
  1006.   SelectFont (systemFont);
  1007.   s = (SlatE) Parent (t);
  1008.   ObjectRect (s, &r);
  1009.   InsetRect (&r, 4, 4);
  1010.   GetNextPosition (t, &npt);
  1011.   tdata.title = NULL;
  1012.   tdata.numPages = 0;
  1013.   tdata.pageHandles = NULL;
  1014.   tdata.numColumns = 0;
  1015.   tdata.colHandles = NULL;
  1016.   tdata.font = font;
  1017.   tdata.topRow = npt.y;
  1018.   tdata.leftMargin = npt.x;
  1019.   tdata.rightMargin = npt.x + minwid;
  1020.   tdata.width = tdata.rightMargin - tdata.leftMargin;
  1021.   SelectFont (font);
  1022.   tdata.lineHeight = LineHeight ();
  1023.   SelectFont (systemFont);
  1024.   tdata.visLines = (r.bottom - r.top + 1) / tdata.lineHeight;
  1025.   tdata.numLines = 0;
  1026.   tdata.currentRow = 0;
  1027.   tdata.tabRow = 0;
  1028.   tdata.returnRow = 1;
  1029.   tdata.currentColumn = 0;
  1030.   tdata.action = actn;
  1031.   SetPanelExtra ((PaneL) t, &tdata);
  1032.   LoadRect (&r, npt.x, npt.y, tdata.rightMargin, npt.y);
  1033.   RegisterRect ((PaneL) t, &r);
  1034.   Break (t);
  1035. }
  1036.  
  1037. static void ResetTable (PaneL t)
  1038.  
  1039. {
  1040.   Int2       i;
  1041.   PagePtr    pagePtr;
  1042.   TableData  tdata;
  1043.  
  1044.   GetPanelExtra (t, &tdata);
  1045.   if (tdata.title != NULL) {
  1046.     HandFree (tdata.title);
  1047.   }
  1048.   if (tdata.pageHandles != NULL) {
  1049.     pagePtr = (PagePtr) HandLock (tdata.pageHandles);
  1050.     for (i = 0; i < tdata.numPages; i++) {
  1051.       HandFree (pagePtr [i]);
  1052.     }
  1053.     HandUnlock (tdata.pageHandles);
  1054.     HandFree (tdata.pageHandles);
  1055.   }
  1056.   if (tdata.colHandles != NULL) {
  1057.     HandFree (tdata.colHandles);
  1058.   }
  1059.   NewTable ((TablE) t, tdata.width, tdata.font, tdata.action);
  1060. }
  1061.  
  1062. extern TablE TablePanel (SlatE s, Int2 minwid, FonT font, TableProc actn)
  1063.  
  1064. {
  1065.   TablE   t;
  1066.   WindoW  tempPort;
  1067.  
  1068.   t = NULL;
  1069.   if (s != NULL) {
  1070.     tempPort = SavePort (s);
  1071.     t = (TablE) CustomPanel (s, DrawTable, sizeof (TableData), ResetTable);
  1072.     if (t != NULL) {
  1073.       SetPanelClick ((PaneL) t, TableClick, NULL, NULL, NULL);
  1074.       NewTable (t, minwid * stdCharWidth, font, actn);
  1075.     }
  1076.     RestorePort (tempPort);
  1077.   }
  1078.   return t;
  1079. }
  1080.